#ifndef H_A2SYSTEM
#define H_A2SYSTEM

#ifndef H_A2SYSDEF
# include "a2sysdef.h"
#endif

#ifndef __FCNTL_H
# ifndef _INC_FCNTL
#  ifndef O_RDONLY
#   include <fcntl.h>
#   include <share.h>
#  endif
# endif
#endif

/*------------------------------------------------------------------*/
/*---------------------------- T Y P E S ---------------------------*/
/*------------------------------------------------------------------*/

#ifdef __FOR_WINDOWS__
 typedef void _huge * V_PTR;
#else
 typedef char * LPSTR;
 typedef const char * LPCSTR;
 typedef void * V_PTR;
#endif

#ifndef _IO_H
# ifndef __IO_H
#  include <io.h>
# endif
#endif

#ifndef __DOS_DEF_
# ifndef __DOS_H
#  include <dos.h>
# endif
#endif

#ifdef __TURBOC__

typedef struct ftime FTIME;

#ifndef __DIR_DEF_
# ifndef __DIR_H
#  ifndef _FFBLK_DEF
#   include <dir.h>
#  endif
# endif
#endif
typedef struct ffblk FFBLK;

#else /*not __TURBOC__*/

#include <direct.h>

typedef struct {
   unsigned ft_sec   : 5;
   unsigned ft_min   : 6;
   unsigned ft_hour  : 5;
   unsigned ft_day   : 5;
   unsigned ft_month : 4;
   unsigned ft_year  : 7;
} FTIME;

typedef struct {
   char     ff_reserved[21];
   char     ff_attrib;
   unsigned ff_ftime;
   unsigned ff_fdate;
   long     ff_fsize;
#if !defined(__FOR_DPMI32__) && !defined(__FOR_WIN32__)
   char     ff_name[13];
#else
   char     ff_name[255];
#endif
#if defined(__FOR_WIN32__)
   long   handle;
   struct _finddata_t ft;
#endif
} FFBLK;

# if !defined(__FOR_DPMI32__) && !defined(__FOR_WIN32__)
#  ifndef MK_FP
#   define MK_FP(seg,ofs)	((void A2FAR *) \
			   (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
#  endif
# endif

# ifndef FA_RDONLY
#  define FA_RDONLY  0x01
#  define FA_HIDDEN  0x02
#  define FA_SYSTEM  0x04
#  define FA_LABEL   0x08
#  define FA_DIREC   0x10
#  define FA_ARCH    0x20
# endif

#endif /*__TURBOC__*/

/*------------------------------------------------------------------*/
/*---------------------- F U N C T I O N S -------------------------*/
/*------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif

int  a2isalpha (int c);
int  a2islower (int c);
int  a2isupper (int c);
int  a2tolower (int c);
int  a2toupper (int c);
char *a2strlwr (unsigned char *s);
char *a2strupr (unsigned char *s);
int  a2stricmp (unsigned char *s1, unsigned char *s2);
int  a2strnicmp(unsigned char *s1, unsigned char *s2, int n);
int  a2memicmp (unsigned char *s1, unsigned char *s2, int n);
int  a2ltrim   (char *s);
int  a2rtrim   (char *s);
int  a2trim    (char *s);

int os_err (int errc);

int A2PAS os_assign (char *newassign, char *oldassign, int oldbsiz);

void A2PAS os_assignnm (char *srcname, char *dstname);

#if defined(__FOR_WINDOWS__) || defined(__FOR_WIN32__) || defined(__FOR_DPMI32__)
# define OS_SETNFILES(NFILES) SetHandleCount(NFILES)
#else
# if defined(__DPMI16__)
#  define OS_SETNFILES(NFILES) {_BX=NFILES; _AH=0x67; geninterrupt(0x21);}
# else
#  define OS_SETNFILES(NFILES)
# endif
#endif

#define osopen(fname) os_open(fname,O_RDWR)
int os_open (LPCSTR fname, int oflags);

#define osclose os_close
int os_close (int fh);

#define osfexist os_exist
int os_exist (LPSTR fname);

#define oscreat(fname) os_creat(fname,0)
int os_creat (LPCSTR fname, int attrib);

int os_read (int fh, V_PTR buf, unsigned len);

int os_write(int fh, V_PTR buf, unsigned len);

int osread (int fn, V_PTR buf, long offset, int blksz);
int oslsrd (int fn, V_PTR buf, long blkn,   int blksz);
int oswrite(int fn, V_PTR buf, long offset, int blksz);
int oslswrt(int fn, V_PTR buf, long blknmb, int blksize, long maxnmb);

int os_flush (int fh);

long  os_lseek (int fh, long offset, int origin);

#define osexepath os_exepath
LPSTR os_exepath(LPSTR exedir);

#define osopeng(fname) os_openg(fname,O_RDWR)
int os_openg (LPSTR fname, int oflags);
int os_opgmode(int mode);
/* global search: 0 - curdir, exedir, nikadir, path */
/*                1 - exedir, curdir, nikadir, path */

#define a2dagfnm os_fullnm
int os_fullnm (LPSTR fname, LPSTR name, char disp);

#define osflsz os_filelength
long  os_filelength (int fh);

int os_chsize (int fh, long newsize);

#define osgetcurdir os_getcurdir
 int os_getcurdir(int drive, LPSTR szDir);

#define osgetcwd os_getcwd
 LPSTR os_getcwd (LPSTR buf, int len);

# define osunlink os_unlink
  int os_unlink (LPSTR fname);


#if !defined(__FOR_WINDOWS__)

# define osgetdisk os_getdisk
  int os_getdisk(void);

# define ossetdisk os_setdisk
  int os_setdisk(int drive);

  int os_remote (int drive);

# define osdiskfree os_diskfree
  long  os_diskfree (int drive);

  int osChkSpace (LPSTR fname);

  int os_fattr (LPSTR fname, int *attrib, int mode);

# define osftime os_ftime
  int os_ftime (LPSTR fname, FTIME *ft, int mode);
  int os_ftime0(int fh, unsigned short *dt, unsigned short *tm, int set);

# define osrename os_rename
  int os_rename (LPSTR oldname, LPSTR newname);

# if !defined(__FOR_WINDOWS__)
#  if defined(__FOR_DOS__) || defined(__FOR_DPMI16__) || defined(NODLL)
#   define oststdr os_tstdr
    int os_tstdr (int drive);
#  endif
# endif

# define osfindfirst os_findfirst
  int os_findfirst (LPSTR fname, FFBLK *ffblk, int attrib);

# define osfindnext os_findnext
  int os_findnext  (FFBLK *ffblk);

#endif /* !(__FOR_WINDOWS__) */


V_PTR os_malloc (unsigned size);
V_PTR os_calloc (unsigned nelem, unsigned elsize);
void  os_free (V_PTR block);
long  os_getmemfree(void);
int os_memlink (int on);
int os_freelink (void);
int os_checklinkmem (void);

#ifdef __FOR_DOS__
# ifdef A2SYSPROG
   extern V_PTR (*a2_ext_malloc)(unsigned size);
   extern int (*a2_ext_free)(V_PTR block);
# endif
int a2memUMB (int set);
int a2memEMS (int set);
int a2memVID (int set);
#else
# define a2memUMB(set) a2dummy_1()
# define a2memEMS(set) a2dummy_1()
# define a2memVID(set) a2dummy_1()
#endif

#define osdatime os_datime
void os_datime (struct a2datetm *pdt);
void os_setdatime(struct a2datetm *pdt);


#ifndef __STRIP_TV__

#define BIOSPRINT os_print
#if !defined(__FOR_WIN32__) && !defined(__FOR_DPMI32__)
 int os_print (int cmd, int abyte, int port);
#else
# define os_print(cmd, abyte, port) 0
#endif

#define M_bioskey os_keybd
int os_keybd (int cmd);

int os_setperiodfunc (int ticks, int (*pfunc)(void));
/* if pfunc return nonzero value it placed into keyboard buffer */

void os_delay (unsigned msec);
void os_sleep (unsigned seconds);

#if !defined(__FOR_WIN32__) && !defined(__FOR_DPMI32__)
 void os_enableInt (void);
 void os_disableInt(void);
#else
# define os_enableInt()
# define os_disableInt()
#endif

#ifdef __WATCOMC__
# pragma aux os_enableInt  = "sti";
# pragma aux os_disableInt = "cli";
#endif

#endif

#ifdef __FOR_DOS__
#define swapexec a2swapexec
int cdecl a2swapexec(char *prog, char *parms);
#else
# if defined(__FOR_DPMI16__) || ((defined(__FOR_DPMI32__) || defined(__FOR_WIN32__)) && defined NODLL)
# define swapexec a2emu_swapexec
int a2emu_swapexec(char *prog, char *parms);
# endif
#endif

#if !defined(__FOR_WINDOWS__) && !defined(__FOR_WIN32__) && !defined(__FOR_DPMI32__)

typedef struct {
   void *DevNext;
   WORD  DevAttr;
   WORD  DevStrt;
   WORD  DevIntr;
   char  DevName[8];
} A2DEVHDR;
enum _errc_errf_masks_ {
   A2HE_ERRMASK = 0xFF,
   A2HE_F_DISK  = (int)0x8000U,
   A2HE_FA_IGNORE=0x2000, A2HE_FA_RETRY=0x1000, A2HE_FA_FAIL=0x800,
   A2HE_AREA    = (0x400+0x200),
   A2HE_WROPER  = 0x100,
   A2HE_DRIVE   = 0xFF
};
enum _errH_retcodes {A2HE_IGNORE, A2HE_RETRY, A2HE_ABORT, A2HE_FAIL};
void cdecl a2hdrerr(
   int (*errH)(A2DEVHDR *pDevH, int errc, int errf), char *stk
);
int a2ErrHandler(A2DEVHDR *pDevH, int errc, int errf);

#else

# define a2hdrerr(pDevH, stk)

#endif

#ifndef A2TV000_SOURCE_FILE
 unsigned cdecl A2Wgtimc (void);
 void     cdecl A2Wbell  (void);
 int      cdecl A2Wgvmode(void);
#endif

int a2dummy0 (void); /* dummy function return  0 */
int a2dummy_1(void); /* dummy function return -1 */

#ifdef __cplusplus
}
#endif

#endif /* H_A2SYSTEM */
